package data;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.List;

import com.google.common.collect.Lists;

public class VotingCard implements Cloneable
{
    private List<Candidate> _candidates = Lists.newLinkedList();
    private BigInteger _id;

    public VotingCard( String cardString )
    {
        String[] splitted = cardString.split( "\r\n" );
        for( int i = 0; i < splitted.length - 1; i++ )
        {
            int lastSpace = splitted[ i ].lastIndexOf( " " );
            if( lastSpace == -1 )
                continue;
            boolean voted = splitted[ i ].substring( lastSpace + 1 ).equals( "t" )? true : false;
            String name = splitted[ i ].substring( 0, lastSpace );
            addVotedCandidate( name, voted );
        }
        try
        {
            _id = new BigInteger( splitted[ splitted.length - 1 ] );
            if( _id.equals( BigInteger.ZERO ) )
                setNewRandomId();
        }
        catch( Exception e )
        {
            setNewRandomId();
        }
    }

    public VotingCard( BigInteger id )
    {
        _id = BigInteger.ONE.add( id );
    }

    public VotingCard( boolean setRandomId )
    {
        if( setRandomId )
            setNewRandomId();
        else
            _id = BigInteger.ZERO;
    }

    public void setNewRandomId()
    {
        SecureRandom sr = null;
        try
        {
            sr = SecureRandom.getInstance( "SHA1PRNG", "SUN" );
        }
        catch( Exception e )
        {
            // unreachable statement
        }
        byte[] bytes = new byte[ 32 ];
        sr.nextBytes( bytes );
        _id = new BigInteger( bytes );
    }

    public VotingCard clone()
    {
        VotingCard v = new VotingCard( _id );
        for( Candidate c: _candidates )
            v.addCandidate( c.getName() );
        return v;
    }

    public boolean addCandidate( String name )
    {
        return _candidates.add( new Candidate( name ) );
    }

    private void addVotedCandidate( String name, boolean voted )
    {
        _candidates.add( new Candidate( name, voted ) );
    }

    public List<Candidate> getVoted()
    {
        List<Candidate> voted = Lists.newLinkedList();
        for( Candidate c: _candidates )
            if( c.isVoted() )
                voted.add( c );
        return voted;
    }

    public void setVoted( int number )
    {
        _candidates.get( number ).vote();
    }

    public List<Candidate> getCandidates()
    {
        return _candidates;
    }

    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        for( Candidate c: _candidates )
        {
            builder.append( c );
            builder.append( "\r\n" );
        }
        builder.append( _id );
        return builder.toString();
    }

    public BigInteger getId()
    {
        return _id;
    }
}
